Skip to content

fix(build): make uv sync work on fresh clones without the private indicium packages#30

Merged
lfnothias merged 2 commits into
mainfrom
fix/uv-sync-indicium-sources
Jul 10, 2026
Merged

fix(build): make uv sync work on fresh clones without the private indicium packages#30
lfnothias merged 2 commits into
mainfrom
fix/uv-sync-indicium-sources

Conversation

@lfnothias

Copy link
Copy Markdown
Collaborator

Summary

uv sync fails on every fresh clone with Distribution not found at: .../indicium, because [tool.uv.sources] points at three private sibling checkouts that exist only on maintainer machines. This removes them and adds two guards so the regression cannot recur silently.

Fixes #29. The same defect was reported as #5 and fixed by #6; commit 940fd36 reintroduced it while restoring the KG test suite.

Why the previous fix did not hold

uv builds a universal lockfile, so uv lock resolves every extra and every dependency-group regardless of which one the user requests. A single undeclarable requirement therefore breaks the default uv sync. The failure happens during resolution, before any Python runs — it reproduces with --offline.

The three packages cannot be declared at all today:

  • indicium, indicium-adapters, indicium-adapters-metabolomics are private repositories.
  • Neither adapter package exists on PyPI.
  • The name indicium on PyPI belongs to an unrelated project (a key-value store, latest 0.1.0a3), so a bare indicium requirement resolves to the wrong package.

Commit 940fd36 re-enabled the extras to restore 43 tests that need indicium. That trade was invisible in CI because the test job installs with pip install -e ".[dev]", and pip ignores [tool.uv.sources] entirely.

Changes

  • pyproject.toml: remove the indicia and adapters extras and the [tool.uv.sources] block. The comment now records why they must never come back, and how a maintainer installs the private stack without editing the file.
  • pyproject.toml: add a public graph = ["rdflib>=6.0", "pyoxigraph>=0.4"] extra. indicium_layer/store.py imports rdflib unconditionally at module level and pyoxigraph for the production store, yet rdflib was never declared anywhere and pyoxigraph was declared only inside the removed indicia extra. Both are on PyPI, so uv sync --extra graph works for everyone.
  • .github/workflows/ci.yml: add a uv-resolve job that runs uv lock on a clean runner. A GitHub runner never has the sibling checkouts, so it is exactly an external user's environment. This is the check that would have caught 940fd36.
  • tests/unit/test_pyproject_packaging.py: a hermetic regression test rejecting local-path [tool.uv.sources] entries and any private distribution declared in base dependencies, extras, or dependency-groups.
  • Rewrite ten runtime error strings and docstrings that instructed users to run uv sync --extra indicia, which now fails with Extra `indicia` is not defined.

Maintainer workflow

The private packages are installed into the synced environment rather than declared:

uv sync --extra dev --extra graph
uv pip install -e ../indicium -e ../indicium-adapters -e ../indicium-adapters-metabolomics
uv sync --inexact --extra dev --extra graph   # --inexact, or uv prunes the editable installs

--inexact is load-bearing: a plain uv sync uninstalls the editable siblings.

Verification

  • uv lock and uv sync --dry-run succeed in a clone with no sibling directories; before the change both emit the reported error.
  • Reconstructing the pre-fix pyproject.toml in an isolated tree makes both the new test and uv lock fail, so the guards are not vacuous. Injecting indicium into [dependency-groups] — which bypasses a naive check — is also rejected.
  • Unit suite with CI's exclusions: 2373 passed, 29 failed. All 29 failures (test_web_app_routes.py, test_usage_guide.py) reproduce identically on main with the same environment and are unrelated to this change. They are being addressed separately.
  • uv sync --extra graph installs rdflib and pyoxigraph.

Notes

Two follow-ups are deliberately out of scope:

  • The KG test modules are still excluded wholesale in CI. Adding pytest.importorskip guards would let the rdflib/pyoxigraph-only tests run there.
  • Publishing indicium under that name is impossible while the PyPI name is taken; a rename or a private index is a separate decision.

@lfnothias lfnothias merged commit 5aae0a1 into main Jul 10, 2026
3 checks passed
@lfnothias lfnothias deleted the fix/uv-sync-indicium-sources branch July 10, 2026 08:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Former indicium bug fixed but not in main .toml

1 participant